#pragma once
#include "LockGuard.hpp"
#include "Task.hpp"
#include "Thread.hpp"
#include "log.hpp"
#include<iostream>
#include <pthread.h>
#include<vector>
#include<queue>

const int g_thread_num=5;
template <class T>
class ThreadPool
{
public:
    pthread_mutex_t* getMutex(){
        return &_lock;
    }
    bool isEmpty(){
        return task_queue.empty();
    }
    void waitCond(){
        pthread_cond_wait(&_cond, nullptr);
    }
    T getTask(){
        T task=task_queue.front();
        task_queue.pop();
        return task;
    }
    static ThreadPool<T>* getThreadPool(int num=g_thread_num)
    {
        if(thread_ptr==nullptr)
        {
            LockGuard lockguard(&_mutex);
            if(thread_ptr==nullptr)
            {
                thread_ptr=new ThreadPool<T>(num);
            }
        }
        return thread_ptr;
    }
    void run()
    {
        for(auto& iter:_threads){
            iter->start();
            logMessage(NORMAL, "%s-%s", iter->name(),"线程启动成功");
        }
    }
    void pushTask(const T& task)
    {
        LockGuard locckguard(&_lock);
        task_queue.push(task);
        pthread_cond_signal(&_cond);
    }
    ~ThreadPool()
    {
        for(auto& iter:_threads){
            iter->join();
            delete iter;
        }
        pthread_mutex_destroy(&_lock);
        pthread_cond_destroy(&_cond);
        pthread_mutex_destroy(&_mutex);
    }
    static void* routine(void* args)
    {
        ThreadData* td=static_cast<ThreadData*>(args);
        ThreadPool<T>* tp=static_cast<ThreadPool<T>*>(td->_args);
        T task;
        {
            LockGuard lockguard(tp->getMutex());
            while(tp->isEmpty()){
                tp->waitCond();
            }
            task=tp->getTask();
        }
        task(td->_name);
    }
private:
    ThreadPool(int thread_num=g_thread_num)
    :_num()
    {
        pthread_mutex_init(&_mutex,nullptr);
        pthread_cond_init(&_cond,nullptr);
        for(int i=0;i<thread_num;i++){
            _threads.push_back(new Thread(i,routine,this));
        }
    }
    ThreadPool<T>& operator=(const ThreadPool<T>&)=delete;
    ThreadPool(const ThreadPool<T>& )=delete;
private:
    int _num;
    std::vector<Thread*> _threads;
    std::queue<T> task_queue;
    pthread_mutex_t _lock;
    pthread_cond_t _cond;
    static pthread_mutex_t _mutex;
    static ThreadPool<T>* thread_ptr;
};
// const int g_thread_num=5;
// template <class T>
// class ThreadPool
// {
// public:
//     pthread_mutex_t* getMutex(){
//         return &_lock;
//     }
//     bool isEmpty(){
//         return task_queue.empty();
//     }
//     void waitCond(){
//         pthread_cond_wait(&_cond,&_lock);
//     }
//     T getTask(){
//         T task=task_queue.front();
//         task_queue.pop();
//         return task;
//     }
//     static ThreadPool<T>* getThreadPool(int num=g_thread_num)
//     {
//         if(thread_ptr==nullptr)
//         {
//             LockGuard lockguard(&_mutex);
//             if(thread_ptr==nullptr){
//                 thread_ptr=new ThreadPool<T>(num);
//             }
//         }
//         return thread_ptr;
//     }
//     void run()
//     {
//         for(auto& iter:_threads){
//             logMessage(NORMAL,
//             "%s %s",iter->name(),"启动成功");
//         }
//     }
//     static void* routine(void* args)
//     {
//         ThreadData* td=(ThreadData*)args;
//         ThreadPool<T>* tp=(ThreadPool<T>*)td->_args;
//         while(true)
//         {
//             T task;
//             {
//                 //获取锁
//                 LockGuard lockguard(tp->getMutex());
//                 while(tp->isEmpty()){
//                     //这里还需要继续等待
//                     tp->waitCond();
//                 }
//                 //获取任务
//                 task=tp->getTask();
//             }
//             //这里就要执行任务了
//             task(td->_name);
//         }
//     }
//     void pushTask(const T& task)
//     {
//         LockGuard lockguard(&_lock);
//         task_queue.push(task);
//         //通知在这个条件变量下等待的线程看看是否已经满足了
//         //执行的条件，如果满足的话无需继续等待
//         pthread_cond_signal(&_cond);
//     }
//     ~ThreadPool(){
//         for(auto& iter:_threads){
//             iter->join();
//             delete iter;
//         }
//         pthread_mutex_destroy(&_lock);
//         pthread_cond_destroy(&_cond);
//     }
// private:    
//     ThreadPool(int thread_num=g_thread_num)
//     :_num(thread_num)
//     {
//         pthread_mutex_init(&_lock, nullptr);
//         pthread_cond_init(&_cond,nullptr);
//         for(int i=0;i<thread_num;i++){
//             _threads.push_back(new Thread(i,routine,this));
//         }
//     }
//     ThreadPool(const ThreadPool<T>& )=delete;
//     ThreadPool<T>& operator=(const ThreadPool<T>&)=delete;
// private:
//     std::vector<Thread*> _threads;
//     std::queue<T> task_queue;
//     int _num;
//     static ThreadPool<T>* thread_ptr;
//     pthread_mutex_t _lock;
//     pthread_cond_t _cond;
//     //因为静态方法没有办法获取非静态的成员变量
//     static pthread_mutex_t _mutex;
// };
